import { Pagination, Table, PaginationProps } from "ant-design-vue";
import Footer from "~/components/FooterWrapper/FooterWrapper.vue";
import { defineComponent, reactive, ref, readonly, onMounted,onActivated } from "vue";
import "./table.less";
import { AutoTableColumns, Column, Pageation, TableContext } from "./types";
import type { TableProps } from "ant-design-vue";
import { TableRowSelection } from "ant-design-vue/es/table/interface";
import {
	buildTableOperation,
	buildTagText,
	buildTbleColumnEllipsis,
} from "./column";
import { computed } from "vue";
import { SizeType } from "ant-design-vue/lib/config-provider/context";
import { isArray, isFunction, isNil,debounce } from "lodash-es";
import { useMounedExection } from "~/utils/hooks/mountd";
import { shallowMerge } from "~utils/shared";
interface IAutoTableProps {
	columns: AutoTableColumns;

	/** 被请求依赖项 **/
	fetchPayload?: Pageation & Dict;
	needIndex?: boolean;

	/** 执行函数 **/
	fetchRemoteDataSource: (
		query: NonNullable<IAutoTableProps["fetchPayload"]>
	) => Promise<MergeType<{ dataSource: any[]; total: number }> | null>;
	restTableProps?: Omit<TableProps, "columns" | "dataSource">;
	restPaginationProps?: PaginationProps;
	needFooterPageation?: "table" | "footer" | "nil";
	rowKey?: string;
	operation?: (type: string, model: Dict) => void;
	rowSelection?: TableRowSelection;
	isSupervision?: boolean
	// filterOperation?:(operation:Operatoin, record:)
	lazyLoad?:false;
	isSort?:boolean
}

const AutoTable = defineComponent({
	props: [
		"rowKey",
		"fetchPayload",
		"fetchRemoteDataSource",
		"columns",
		"rowSelection",
		"restTableProps",
		"needIndex",
		"needFooterPageation",
		"restPaginationProps",
		"filterOperation",
		"isSupervision",
		"lazyLoad",
		"isSort",
		"customRow"
	],
	emits: ["operation","expand"],
	setup(props: IAutoTableProps, ctx) {
		const {
			fetchRemoteDataSource,
			needFooterPageation = "footer",
			columns = [],
			needIndex = false,
			rowKey = "id",
			lazyLoad=false,
			fetchPayload = {} as NonNullable<IAutoTableProps["fetchPayload"]>,
		} = props;

		const { onChange, ...restPaginationProps } = props.restPaginationProps ?? {};
		const { ...restTableProps } = props.restTableProps ?? {};

		const processState = reactive<{
			loading: boolean;
			total: number;
			dataSource: Dict[];
		}>({
			loading: true,
			total: 0,
			dataSource: [],
		});


		let oldPagePrevPageSize = fetchPayload.size;

		const fetchRemoteDataSourceImpl2 = async <T = any,>(
			nextFetchPayload?: T
		) => {
				try {
					processState.loading = true;
					processState.dataSource = [];

					const finishNextPayload = shallowMerge(
						{},
						fetchPayload,
						nextFetchPayload
					);
					const request =
						typeof fetchRemoteDataSource === "function"
							? fetchRemoteDataSource
							: () => Promise.resolve(null);
					const rs = await request(finishNextPayload);

					if (!isNil(rs)) {
						processState.dataSource = rs.dataSource;
						processState.total = rs.total;
						return;
					}
				} finally {
					processState.loading = false;
				}
		};
		// 请求函数执行添加防抖，主动调用和参数更新调用重复调用多次
		const fetchRemoteDataSourceImpl =  debounce(fetchRemoteDataSourceImpl2,200);



		const stopOfDataFetch = useMounedExection(
			fetchPayload as any,
			fetchRemoteDataSourceImpl
		);

		const provideContext: TableContext = readonly({
			refetch: fetchRemoteDataSourceImpl,
			fetchLoading(loading?: boolean) {
				if (typeof loading === "boolean") {
					processState.loading = loading;
				}
				return processState.loading;
			},
			clear() {
				stopOfDataFetch();
				processState.total = 0;
				processState.dataSource.length = 0;
			},
			syncUpdateDataSource(callback) {
				processState.dataSource = callback(
					processState.dataSource as any
				) as any;
			},
			// todo:尽量不要对外暴露
			processState: processState,
		});

		ctx.expose(provideContext);

		// 多个参数
		const listenerOfPaginationChangne = (current: number, pageSize: number) => {
			if (oldPagePrevPageSize !== pageSize) {
				fetchPayload.current = 1;
			}
			else {
				fetchPayload.current = current;
			}

			fetchPayload.size = oldPagePrevPageSize = pageSize;

			onChange?.(current, pageSize);
		};
		let expandedRowKeys=ref([]);
		if (restTableProps.defaultExpandedRowKeys){
			expandedRowKeys=ref([...restTableProps.defaultExpandedRowKeys]);
		}
		const expand = (expanded, record) => {
			console.log(expanded, record,lazyLoad);



				if (expanded) {
					if (lazyLoad){
						console.log(1);

						expandedRowKeys.value=[];
						expandedRowKeys.value.push(record[rowKey]);
						ctx.emit("expand", record[rowKey]);
					}
					else {
						expandedRowKeys.value.push(record[rowKey]);
					}
				}
				else {
				if (lazyLoad){
					console.log(2);

					expandedRowKeys.value=[];
					return;
				}

				const index=expandedRowKeys.value.indexOf(record[rowKey]);
				if (index > -1){
					expandedRowKeys.value.splice(index,1);
				}
				}
				console.log(expandedRowKeys.value);
		};
		const listenerOfTableChange = (...args) => {
			const [, , sorter, t] = args;
			if (t.action === "sort") {
				fetchPayload.desc = fetchPayload.asc = null;
				if (!isNil(sorter.order)) {
					fetchPayload[sorter.order === "ascend" ? "asc" : "desc"] = sorter.field ?? null;
				}
			}
		};

		const emitsTableOperation = (type: string, column: Dict) => {
			ctx.emit("operation", type, column);
		};

		const totalComputed = computed(() => {
			return fetchPayload.current * fetchPayload.size;
		});

		// 表格中增加序号
		const renderIndexNode = ({ index }: UsedDict<{ index: number }>) => {
			try {
				const i = totalComputed.value - (fetchPayload.size - 1) + index;
				return i;
			} catch (exx) {
				console.log(exx);
				return index;
			}
		};

		const tableSize = ref<SizeType>("middle");
		const nodeRef = ref<HTMLDivElement>(null);

		const tableScroll = ref(0);

		onMounted(() => {
			const dom = nodeRef.value;
			const root = document.documentElement;
			// padding+height
			const offset = 44 + 140;
			globalThis.addEventListener("resize", (e) => {
				const { innerWidth } = e.target as Window;

				let v = root.clientHeight - dom.offsetTop - offset;
				if (v < 300) {
					v = 300;
				}

				tableScroll.value = (props.isSupervision ? v-50 : v);
				if (innerWidth >= 2100) {
					tableSize.value = "large";
					return;
				}
				if (innerWidth < 900) {
					tableSize.value = "small";
					return;
				}
				if (innerWidth < 1920) {
					tableSize.value = "middle";
					return;
				}
			});
			tableScroll.value =
				document.documentElement.clientHeight -
				(dom as HTMLDivElement).offsetTop -
				44 -
				126 - (props.isSupervision ? 70 : 0);
				completeColumns();
		}
		);
		onActivated(()=>{
			const dom = nodeRef.value;
			tableScroll.value =
			document.documentElement.clientHeight -
			(dom as HTMLDivElement).offsetTop -
			44 -
			126 - (props.isSupervision ? 70 : 0);
		});
		// / 分页相关
		const restPaginationPropsMerged = {
			...(restPaginationProps ?? {}),
			pageSizeOptions: ["10", "20", "30", "50", "100"],
			onChange: listenerOfPaginationChangne,
			showSizeChanger: true,
		};
		const resolveColumns: Column[] = reactive( needIndex
		? [{
			title: "序号",
			width: 60,
			align: "center",
			dataIndex: "customIndex",
			resizable:true,
			customRender: renderIndexNode,
		}] : []
		);
		const completeColumns = () => {
			// 根据columns里面的每一项派生出新的next(column)
			for (let i = 0, len = columns.length; i < len; i++) {
				const item = columns[i];
				let next: Column = item;
				item.resizable = true;
				if (
					item.dataIndex === "operation" ||
					isArray(item.operations) ||
					isFunction(item.operations)
				) {
					next = buildTableOperation(item, emitsTableOperation);
				}
				if (!isNil(item.ellipsis)) {
					next = buildTbleColumnEllipsis(item);
				}
				if (!isNil(item.shouldTagText)) {
					next = buildTagText(item);
				}
				if (item.sorter === true) {
					let sortOrder: boolean | string = false;

					if (typeof fetchPayload.asc === "string") {
						sortOrder = "ascend";
					}
					if (typeof fetchPayload.desc === "string") {
						sortOrder = "descend";
					}

					next = {
						...next,
						defaultSortOrder: sortOrder as any,
					};
				}
				resolveColumns.push(next);
			}
		};
		const handleResizeColumn = (w, col) => {
			col.width = w;
		};
		const bodyCell = (renderRecord: RowInputForTable) => {
			if (typeof renderRecord.column.customRender === "function") {
				return renderRecord.column.customRender(renderRecord);
			}

			return ctx.slots.bodyCell?.(renderRecord);
		};
		return () => {
			return (
				<>
					<div ref={nodeRef} class="auto-table-inner-width"></div>
					<Table
						rowKey={rowKey}
						size={tableSize.value}
						loading={processState.loading}
						v-slots={{ ...ctx.slots, bodyCell }}
						scroll={{ y: tableScroll.value }}
						rowSelection={props.rowSelection}
						onChange={listenerOfTableChange}
						onExpand={expand}
						expandedRowKeys={expandedRowKeys.value}
						columns={resolveColumns}
						dataSource={processState.dataSource}
						onResizeColumn={handleResizeColumn}
						customRow={props.isSort? props.customRow:null}
						pagination={
							needFooterPageation === "table" ?
								{
									total: processState.total,
									disabled: processState.loading,
									position: ["bottomCenter"],
									current: fetchPayload.current,
									size: "default",
									pageSize: fetchPayload.size,
									showTotal: (total) => (
										<span class="show-page-total">共{total}条数据</span>
									),
									...restPaginationPropsMerged,
								} : false}
						{...restTableProps}
					/>
					{needFooterPageation === "footer" && (
						<Footer>
							<Pagination
								pageSize={fetchPayload.size}
								disabled={processState.loading}
								current={fetchPayload.current}
								total={processState.total}
								showTotal={(total) => (
									<span class="show-page-total">共{total}条数据</span>
								)}
								{...restPaginationPropsMerged}
							/>
						</Footer>
					)}
				</>
			);
		};
	},
});

export default AutoTable;
